<?php
	
	/**
	  *	This file is responsible for defining a class
	  *
	  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
	  *	@version 0.0
	  */
	
	if ( !defined( 'SECURITY' ) ) {
		die( 'Direct access to this script is not allowed!' );
	}
	
	/**
	  *	This class is responsible for retrieving documentator information
	  *
	  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
	  *	@version 0.0
	  */
	class Retriever {
		
		/**
		  *	This method stores path information into session
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0
		  *
		  *	@p string type - name of path element
		  *	@p string value - path element value
		  */
		public static function savePath( $type, $value ) {
			
			if ( !isset( $_SESSION['path'] ) ) {
				$_SESSION['path'] = array();
			}
			
			if ( is_null( $value ) ) {
				$value = !empty( $_SESSION['path'][$type] ) || ( ( isset( $_SESSION['path'][$type] ) && ( $_SESSION['path'][$type] == 0 ) ) ) ? $_SESSION['path'][$type] : null;
			}
			
			$_SESSION['path']['current'] = $type;
			$_SESSION['path'][$type] = $value;
			
		}
		
		/**
		  *	This method gathers all current path information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getPlaceInfo() {
			
			if ( isset( $_SESSION['path'] ) ) {
				return $_SESSION['path'];
			} else {
				return array(
					'current' => 'root',
					'path' => array(
						'root' => 'root',
					),
				);
			}
			
		}
		
		/**
		  *	This method gathers a list of available packages
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array of string packets
		  */
		public static function getPackets() {
			
			$packet_list = array_keys( CmsDocumentatorConfig::$packets );
			return $packet_list;
			
		}
		
		/**
		  *	This method gathers a list of versions for current package
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string versions or false on error
		  */
		public static function getVersions() {
			
			$session_info = Retriever::getPlaceInfo();
			
			if ( !isset( $session_info['packet'] ) ) {
				return false;
			}
			
			$packet = $session_info['packet'];
			
			$packets = Retriever::getPackets();
			
			if ( !in_array( $packet, $packets ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			
			$files = SimpleFile::getFiles( array( 'address' => $packet_address ) );
			
			if ( empty( $files ) ) {
				$files = array();
			}
			
			return $files;
			
		}
		
		/**
		  *	This method gathers a list of available files for current packet version
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string files or false on error
		  */
		public static function getFiles() {
			
			$versions = array();
			
			if ( false == $versions = Retriever::getVersions() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			
			if ( !in_array( $version, $versions ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$version_path = $packet_address . '/' . $version . '/files';
			
			$files = SimpleFile::getFiles( array( 'address' => $version_path ) );
			
			if ( empty( $files ) ) {
				$files = array();
			}
			
			return $files;
			
		}
		
		/**
		  *	This method gathers a list of available classes for current packet version
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string classes or false one error
		  */
		public static function getClasses() {
			
			$versions = array();
			
			if ( false == $versions = Retriever::getVersions() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			
			if ( !in_array( $version, $versions ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$version_path = $packet_address . '/' . $version . '/classes';
			
			$files = SimpleFile::getFiles( array( 'address' => $version_path ) );
			
			if ( empty( $files ) ) {
				$files = array();
			}
			
			return $files;
			
		}
		
		/**
		  *	This method gathers a list of available defines for current file
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string defines or false on error
		  */
		public static function getDefines() {
			
			$files = array();
			
			if ( false == $files = Retriever::getFiles() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$file = $session_info['file'];
			
			if ( !in_array( $file, $files ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$defines_path = $packet_address . '/' . $version . '/files/' . $file . '/defines';
			
			$defines = SimpleFile::getFiles( array( 'address' => $defines_path ) );
			
			if ( empty( $defines ) ) {
				$defines = array();
			}
			
			return $defines;
			
		}
		
		/**
		  *	This method gathers a list of available methods for current class
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string methods or false on error
		  */
		public static function getMethods() {
			
			$classes = array();
			
			if ( false == $classes = Retriever::getClasses() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$class = $session_info['class'];
			
			if ( !in_array( $class, $classes ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$methods_path = $packet_address . '/' . $version . '/classes/' . $class . '/methods';
			
			$methods = SimpleFile::getFiles( array( 'address' => $methods_path ) );
			
			if ( empty( $methods ) ) {
				$methods = array();
			}
			
			return $methods;
			
		}
		
		/**
		  *	This method gathers a list of available properties for current class
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string classes or false on error
		  */
		public static function getProperties() {
			
			$classes = array();
			
			if ( false == $classes = Retriever::getClasses() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$class = $session_info['class'];
			
			if ( !in_array( $class, $classes ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$properties_path = $packet_address . '/' . $version . '/classes/' . $class . '/properties';
			
			$properties = SimpleFile::getFiles( array( 'address' => $properties_path ) );
			
			if ( empty( $properties ) ) {
				$properties = array();
			}
			
			return $properties;
			
		}
		
		/**
		  *	This method gathers a list of todos
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of string todos or false on error
		  */
		public static function getTodos() {
			
			$todo_array = array();
			
			$versions = array();
			
			if ( false == $versions = Retriever::getVersions() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			
			if ( !in_array( $version, $versions ) ) {
				return false;
			}
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$todo_path = $packet_address . '/' . $version . '/todos';
			
			$lines = SimpleFile::getLines( array( 'address' => $todo_path, 'external_address' => true ) );
			
			if ( !empty( $lines ) ) {
				$todo_array = $lines;
			}
			
			return $todo_array;
			
		}
		
		/**
		  *	This method gathers all current packet information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getPacket() {
			
			$packets = array();
			
			if ( false == $packets = Retriever::getPackets() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			
			if ( !in_array( $packet, $packets ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$desc_path = $packet_address . '/desc';
			
			$result['desc']['description'] = SimpleFile::getLines( array( 'address' => $desc_path, 'include_empty' => true, 'external_address' => true ) );
			
			return $result;
			
		}
		
		/**
		  *	This method gathers all current packet version information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getVersion() {
			
			$versions = array();
			
			if ( false == $versions = Retriever::getVersions() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			
			if ( !in_array( $version, $versions ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$desc_path = $packet_address . '/' . $version . '/desc';
			
			$result['desc']['description'] = SimpleFile::getLines( array( 'address' => $desc_path, 'include_empty' => true, 'external_address' => true ) );
			
			return $result;
			
		}
		
		/**
		  *	This method gathers all current file information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getFile() {
			
			$files = array();
			
			if ( false == $files = Retriever::getFiles() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$file = $session_info['file'];
			
			if ( !in_array( $file, $files ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$file_path = $packet_address . '/' . $version . '/files/' . $file;
			
			// Get description
			
			$desc = array();
			
			$lines = SimpleFile::getLines( array( 'address' => $file_path . '/desc', 'include_empty' => true, 'external_address' => true ) );
			
			if ( !empty( $lines ) ) {
				
				$last_author_line = -1;
				$desc['authors'] = array();
				$desc['description'] = array();
				
				foreach( $lines as $key => $line ) {
					
					if ( $key == 1 ) {
						$desc['version'] = $line;
					} elseif ( $key == 2 ) {
						$last_author_line = $line + 2;
					} elseif ( $key <= $last_author_line ) {
						$desc['authors'][] = $line;
					} else {
						$desc['description'][] = $line;
					}
					
				}
				
			}
			
			$result['desc'] = $desc;
			
			// Get classes
			
			$result['classes'] = SimpleFile::getLines( array( 'address' => $file_path . '/classes', 'external_address' => true ) );
			
			// Get defines
			
			$result['defines'] = Retriever::getDefines();
			
			return $result;
			
		}
		
		/**
		  *	This method gathers all current class information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getClass() {
			
			$classes = array();
			
			if ( false == $classes = Retriever::getClasses() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$class = $session_info['class'];
			
			if ( !in_array( $class, $classes ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$class_path = $packet_address . '/' . $version . '/classes/' . $class;
			
			// Get description
			
			$desc = array();
			
			$lines = SimpleFile::getLines( array( 'address' => $class_path . '/desc', 'include_empty' => true, 'external_address' => true ) );
			
			if ( !empty( $lines ) ) {
				
				$last_author_line = -1;
				$desc['authors'] = array();
				$desc['description'] = array();
				$desc['rights'] = '';
				
				foreach( $lines as $key => $line ) {
					
					if ( $key == 1 ) {
						$desc['version'] = $line;
					} elseif ( $key == 2 ) {
						$last_author_line = $line + 2;
					} elseif ( $key <= $last_author_line ) {
						$desc['authors'][] = $line;
					} elseif ( $key == $last_author_line + 1 ) {
						$desc['rights'] = $line;
					} else {
						$desc['description'][] = $line;
					}
					
				}
				
			}
			
			$result['desc'] = $desc;
			
			// Get methods
			
			$result['methods'] = Retriever::getMethods();
			
			// Get properties
			
			$result['properties'] = Retriever::getProperties();
			
			return $result;
			
		}
		
		/**
		  *	This method gathers all current define information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getDefine() {
			
			$defines = array();
			
			if ( false == $defines = Retriever::getDefines() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$file = $session_info['file'];
			$define = $session_info['define'];
			
			if ( !in_array( $define, $defines ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$define_path = $packet_address . '/' . $version . '/files/' . $file . '/defines/' . $define;
			
			$result['desc'] = array();
			$result['desc']['description'] = SimpleFile::getLines( array( 'address' => $define_path, 'include_empty' => true, 'external_address' => true ) );
			
			return $result;
			
		}
		
		/**
		  *	This method gathers all current method information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getMethod() {
			
			$methods = array();
			
			if ( false == $methods = Retriever::getMethods() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$class = $session_info['class'];
			$method = $session_info['method'];
			
			if ( !in_array( $method, $methods ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$method_path = $packet_address . '/' . $version . '/classes/' . $class . '/methods/' . $method;
			
			$desc = array();
			
			$lines = SimpleFile::getLines( array( 'address' => $method_path, 'include_empty' => true, 'external_address' => true ) );
			
			if ( !empty( $lines ) ) {
				
				$last_author_line = -1;
				$parameters_left = 0;
				$parameters_count = 0;
				//$parameter_lines_left = -1;
				$parameter_lines_left = 0;
				$return_lines_left = 0;
				$return_lines_count = -1;
				$first_parameter_line = false;
				$got_rights = false;
				$desc['authors'] = array();
				$desc['parameters'] = array();
				$desc['return'] = array();
				$desc['description'] = array();
				$desc['rights'] = '';
				
				foreach( $lines as $key => $line ) {
					
					if ( $key == 1 ) {
						$desc['version'] = $line;
					} elseif ( $key == 2 ) {
						$last_author_line = $line + 2;
					} elseif ( $key <= $last_author_line ) {
						$desc['authors'][] = $line;
					} elseif ( $key == $last_author_line + 1 ) {
						$parameters_left = $line;
						$parameters_count = $line;
					} elseif ( ( $parameters_left > 0 ) && ( $parameter_lines_left == 0 ) ) {
						$parameter_lines_left = $line;
						$first_parameter_line = true;
					} elseif ( $parameter_lines_left > 0 ) {
						
						if ( $first_parameter_line ) {
							
							$info = $line;
							list( $parameter_type, $data_type ) = explode( ' ', $line );
							$desc['parameters'][$parameters_count - $parameters_left]['parameter_type'] = $parameter_type;
							$desc['parameters'][$parameters_count - $parameters_left]['data_type'] = $data_type;
							$first_parameter_line = false;
							$parameter_lines_left--;
							
						} else {
							
							$desc['parameters'][$parameters_count - $parameters_left]['description'][] = $line;
							$parameter_lines_left--;
							
							if ( $parameter_lines_left == 0 ) {
								$parameters_left--;
							}
							
						}
						
					} elseif ( ( $parameters_left == 0 ) && ( $return_lines_count == -1 ) ) {
						
						$return_lines_count = $line;
						$return_lines_left = $line;
						
					} elseif( ( $return_lines_left == $return_lines_count ) && ( $return_lines_left != 0 ) ) {
						
						$desc['return']['data_type'] = $line;
						$return_lines_left--;
						
					} elseif ( $return_lines_left > 0 ) {
						
						$desc['return']['description'][] = $line;
						$return_lines_left--;
						
					} elseif( !$got_rights ) {
						
						$desc['rights'] = $line;
						$got_rights = true;
						
					} else {
					
						$desc['description'][] = $line;
						
					}
					
				}
				
			}
			
			$result['desc'] = $desc;
			
			return $result;
			
		}
		
		/**
		  *	This method gathers all current property information
		  *
		  *	@author Vytenis Urbonavicius <vytenis.urbonavicius@myhost.lt>
		  *	@version 0.0 
		  *
		  *	@return array/false array of info or false on error
		  */
		public static function getProperty() {
			
			$properties = array();
			
			if ( false == $properties = Retriever::getProperties() ) {
				return false;
			}
			
			$session_info = Retriever::getPlaceInfo();
			
			$packet = $session_info['packet'];
			$version = $session_info['version'];
			$class = $session_info['class'];
			$property = $session_info['property'];
			
			if ( !in_array( $property, $properties ) ) {
				return false;
			}
			
			$result = array();
			
			$packet_address = constant( 'DATA_ADDRESS' ) . '/' . $packet;
			$property_path = $packet_address . '/' . $version . '/classes/' . $class . '/properties/' . $property;
			
			$desc = array();
			
			$lines = SimpleFile::getLines( array( 'address' => $property_path, 'include_empty' => true, 'external_address' => true ) );
			
			if ( !empty( $lines ) ) {
				
				$last_author_line = -1;
				$desc['authors'] = array();
				$desc['description'] = array();
				$desc['rights'] = '';
				
				foreach( $lines as $key => $line ) {
					
					if ( $key == 1 ) {
						$desc['version'] = $line;
					} elseif ( $key == 2 ) {
						$last_author_line = $line + 2;
					} elseif ( $key <= $last_author_line ) {
						$desc['authors'][] = $line;
					} elseif ( $key == $last_author_line + 1 ) {
						$desc['rights'] = $line;
					} elseif ( $key == $last_author_line + 2 ) {
						$desc['data_type'] = $line;
					} else {
						$desc['description'][] = $line;
					}
					
				}
				
			}
			
			$result['desc'] = $desc;
			
			return $result;
			
		}
		
	}
	
?>